package com.vanysoft.business.base.role.service;

import com.baomidou.mybatisplus.plugins.Page;
import com.vanysoft.business.base.menu.dao.BaseMenuMapper;
import com.vanysoft.business.base.org.dao.BaseOrgMapper;
import com.vanysoft.business.base.role.dao.BaseRoleFunctionsMapper;
import com.vanysoft.business.base.role.dao.BaseRoleMapper;
import com.vanysoft.business.base.role.entity.TBaseRole;
import com.vanysoft.business.base.role.entity.TBaseRoleFunctions;
import com.vanysoft.business.base.user.dao.BaseUserRolesMapper;
import com.vanysoft.business.base.user.entity.TBaseUserRoles;
import com.vanysoft.business.index.dao.LoginMapper;
import com.vanysoft.common.utils.string.StringUtil;
import com.vanysoft.framework.constants.DbConstants;
import com.vanysoft.framework.exception.VanySoftBaseException;
import com.vanysoft.framework.messagesource.MessageCodeConstant;
import com.vanysoft.framework.utils.CommonUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 项目名称：SharpClaw移动门户
 * 类名称：RoleService
 * 类描述：角色管理
 * 创建人：SharpClaw_x
 * 创建时间：2017年5月31日 下午6:44:53
 * 修改人：SharpClaw_x
 * 修改时间：2017年5月31日 下午6:44:53
 * 版本信息：@version 1.0
 * Copyright (c) 2017SharpClaw-版权所有
 * 修改备注：
 */
@Service
@Transactional(readOnly = true)
public class BaseRoleService {
    /**
     * 内部人员
     */
    public static String ISSYSTEMROLE = "0";
    @Autowired
    private BaseRoleMapper baseRoleMapper;
    @Autowired
    private BaseUserRolesMapper tBaseUserRolesMapper;
    @Autowired
    private BaseOrgMapper baseOrgMapper;
    @Autowired
    private BaseRoleFunctionsMapper baseRoleFunctionsMapper;
    @Autowired
    private BaseMenuMapper baseMenuMapper;
    @Autowired
    private LoginMapper loginMapper;

    /**
     * Function Name               loadRoleInfo
     *
     * @param userId
     * @param roleName
     * @return
     * @description 加载角色名称
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年5月31日 下午6:45:18           SharpClaw_x                    Initial
     * *********************************************************************
     */
    public List<TBaseRole> loadRoleInfo(String userId, String roleName) {
        int adminFlag = loginMapper.checkAdminByUserId(userId);
        if (adminFlag == 0) {
            //为0当前登录用户为普通角色，非administrator角色
            return baseRoleMapper.loadRole(userId, roleName);
        } else {
            //为1则代表administrator角色,administrator拥有所有功能权限
            return baseRoleMapper.loadRoleAll(roleName);
        }
    }

    /**
     * Function Name               queryRoles
     *
     * @param pageSize
     * @param pageNum
     * @param roleName
     * @return
     * @throws VanySoftBaseException
     * @description 查询组织机构下的人
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年5月24日 上午10:04:59           SharpClaw_x      Initial
     * *********************************************************************
     */
    public Map<String, Object> queryRoles(String userId, Integer pageSize, Integer pageNum, String roleName, String status) throws VanySoftBaseException {
        Map<String, Object> users = new HashMap<String, Object>();
        int adminFlag = loginMapper.checkAdminByUserId(userId);

        if (roleName == null || StringUtils.isEmpty(roleName.trim())) {
            roleName = null;
        } else {
            roleName = StringUtils.upperCase(roleName.trim());
        }

        if (StringUtils.isEmpty(status)) {
            status = null;
        }

        //分页工具
        Page<Map<String, Object>> page = new Page<>(pageNum, pageSize);
        if (adminFlag == 0) {
            //为0当前登录用户为普通角色，非administrator角色
            List<TBaseRole> userList = baseRoleMapper.queryRoles(page, userId, roleName, status);

            int forBidden = baseRoleMapper.queryForbiddenRoles(userId, roleName);
            int NotForBidden = baseRoleMapper.queryNotForbiddenRoles(userId, roleName);
            users.put("rows", userList);
            users.put("total", page.getTotal());
            users.put("forBidden", forBidden);
            users.put("NotForBidden", NotForBidden);
        } else {
            //为1则代表administrator角色,administrator拥有所有功能权限
            List<TBaseRole> roleList = baseRoleMapper.queryRolesAll(page, roleName, status);

            int forBidden = baseRoleMapper.queryForbiddenRolesAll(roleName);
            int NotForBidden = baseRoleMapper.queryNotForbiddenRolesAll(roleName);
            users.put("rows", roleList);
            users.put("total", page.getTotal());
            users.put("forBidden", forBidden);
            users.put("NotForBidden", NotForBidden);
        }
        return users;
    }

    /**
     * Function Name               addRole
     *
     * @param roleName
     * @return
     * @throws VanySoftBaseException
     * @description 角色添加
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年6月1日 下午3:44:52           SharpClaw_x                    Initial
     * *********************************************************************
     */
    @Transactional
    public String addRole(String description, String roleName, String userId, String status) throws VanySoftBaseException {
        TBaseRole role = new TBaseRole();
        role.setRoleCode(UUID.randomUUID().toString());
        role.setRoleName(roleName);
        role.setDescription(description);
        role.setOwner(userId);
        role.setUpdateTime(new Date());
        role.setIsAvailable(DbConstants.IS_AVAILABLE);
        role.setStatus(status);
        baseRoleMapper.insert(role);

        return MessageCodeConstant.RTN_CODE_SUCCESS;
    }

    private boolean checkRoleCode(String roleCode) {
        TBaseRole role = baseRoleMapper.selectByPrimaryKey(roleCode);
        boolean check = false;
        if (role != null) {
            check = true;
        }
        return check;
    }

    /**
     * Function Name               modifyRoleInfo
     *
     * @param roleCode
     * @param roleName
     * @param userId
     * @param description
     * @return
     * @description 修改角色
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年6月28日 下午5:23:10           SharpClaw_x                    Initial
     * *********************************************************************
     */
    @Transactional
    public String modifyRoleInfo(String roleCode, String roleName, String userId,
                                 String description, String status) {

        TBaseRole role = baseRoleMapper.selectByPrimaryKey(roleCode);
        role.setRoleName(roleName);
        role.setDescription(description);
        ;
        role.setOwner(userId);
        role.setUpdateTime(new Date());
        role.setIsAvailable(DbConstants.IS_AVAILABLE);
        role.setStatus(status);
        baseRoleMapper.updateByPrimaryKey(role);

        return MessageCodeConstant.RTN_CODE_SUCCESS;
    }

    /**
     * Function Name               deleteRole
     *
     * @param roleCodes
     * @return
     * @description 删除角色
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年6月1日 下午4:42:18           SharpClaw_x                    Initial
     * *********************************************************************
     */
    @Transactional
    public String deleteRole(String roleCodes) {
        if (StringUtils.isBlank(roleCodes)) {
            throw new VanySoftBaseException(MessageCodeConstant.RTN_CODE_UNKNOW_ERROR, "roleCodes is null");
        }
        String[] roleCode = roleCodes.split(",");
        for (int i = 0; i < roleCode.length; i++) {
            //删除角色人员
            baseRoleMapper.deleteRoleUserByroleCode(roleCode[i]);
//			TBaseRole role=baseRoleMapper.selectByPrimaryKey(roleCode[i]);
//			role.setIsAvailable(DbConstants.IS_NOT_AVAILABLE);
//			baseRoleMapper.updateByPrimaryKey(role);
            try {
                baseRoleMapper.deleteByPrimaryKey(roleCode[i]);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                throw new VanySoftBaseException(MessageCodeConstant.RTN_CODE_UNKNOW_ERROR, "请检查该角色下面是否有用户存在");
            }
        }
        return MessageCodeConstant.RTN_CODE_SUCCESS;
    }

    /**
     * Function Name               modifyRoleStatus
     *
     * @param roleCode
     * @param isEnable
     * @return
     * @description 启用或禁用
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年6月1日 下午4:47:33           SharpClaw_x                    Initial
     * *********************************************************************
     */
    @Transactional
    public String modifyRoleStatus(String roleCode, String isEnable) {
        TBaseRole role = baseRoleMapper.selectByPrimaryKey(roleCode);
        role.setStatus(isEnable);
        baseRoleMapper.updateByPrimaryKey(role);
        return MessageCodeConstant.RTN_CODE_SUCCESS;
    }


    /**
     * Function Name               loadRoleUserInfo
     *
     * @param roleCode
     * @param searchKey
     * @return
     * @description 加载角色人员
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年6月1日 下午5:00:00           SharpClaw_x                    Initial
     * *********************************************************************
     */
    public Page<Map<String, Object>> loadRoleUserInfo(String roleCode, String searchKey, Integer pageNum, Integer pageSize) {
        Page<Map<String, Object>> page = new Page<>(pageNum, pageSize);
        List<Map<String, Object>> resultList = baseRoleMapper.loadRoleUserInfo(page, roleCode, searchKey);
        page.setRecords(resultList);
        return page;
    }

    /**
     * Function Name               modifyRoleUser
     *
     * @param roleCode
     * @param userIds
     * @return
     * @throws VanySoftBaseException
     * @description 添加角色人员
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年6月1日 下午6:39:49           SharpClaw_x                    Initial
     * *********************************************************************
     */
    @Transactional
    public String modifyRoleUser(String roleCode, String userIds) throws VanySoftBaseException {
        if (StringUtils.isEmpty(userIds)) {
            throw new VanySoftBaseException(MessageCodeConstant.RTN_CODE_UNKNOW_ERROR, "userIds is null");
        }
        String[] userCode = userIds.split(",");
        for (int i = 0; i < userCode.length; i++) {
            List<Map<String, Object>> roleUserlist = tBaseUserRolesMapper.selectRoleUser(userCode[i], roleCode);
            if (roleUserlist != null && roleUserlist.size() > 0) {
                continue;//该角色有该人了就不添加了
            }
            TBaseUserRoles userRole = new TBaseUserRoles();
            userRole.setUserRoleId(UUID.randomUUID().toString());
            userRole.setUserId(userCode[i]);
            userRole.setRoleCode(roleCode);
            tBaseUserRolesMapper.insert(userRole);
        }
        return MessageCodeConstant.RTN_CODE_SUCCESS;
    }

    /**
     * Function Name               deleteRoleUser
     *
     * @param roleCode
     * @param userIds
     * @return
     * @throws VanySoftBaseException
     * @description 角色人员移除
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年6月1日 下午6:51:14           SharpClaw_x                    Initial
     * *********************************************************************
     */
    @Transactional
    public String deleteRoleUser(String roleCode, String[] userIds) throws VanySoftBaseException {
        if (userIds == null || userIds.length == 0) {
            throw new VanySoftBaseException(MessageCodeConstant.RTN_CODE_UNKNOW_ERROR, "userIds is null");
        }
        for (int i = 0; i < userIds.length; i++) {
            baseRoleMapper.deleteRoleUser(roleCode, userIds[i]);
        }
        return MessageCodeConstant.RTN_CODE_SUCCESS;
    }


    /**
     * Function Name               loadFunctionByRoleCode
     *
     * @param loginUserCode
     * @param roleCode
     * @return
     * @description 根据角色代码查询已分配功能权限和未分配功能权限
     * <p>
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年6月7日 上午11:19:54          SharpClaw_x                     Initial
     * *********************************************************************
     */
    @SuppressWarnings("rawtypes")
    @Transactional
    public Map<String, Object> loadFunctionByRoleCode(String loginUserCode, String roleCode) {
        //当前登录账户
        if (StringUtils.isEmpty(loginUserCode)) {
            loginUserCode = "";
        }
        //所选角色编号
        if (StringUtils.isEmpty(roleCode)) {
            roleCode = "";
        }

        int adminFlag = loginMapper.checkAdminByUserId(loginUserCode);
        Map<String, Object> resultMap = new HashMap<>();
        String loginUserFunctions = "";
        if (adminFlag == 0) {
            //1.当前登录用户拥有菜单功能权限字符串-(非递归去重)
            loginUserFunctions = baseRoleFunctionsMapper.loadFunctionByUserCodeUnion(loginUserCode);
        } else {
            //为1则代表administrator角色,administrator拥有所有功能权限
            List<String> adminFunction = baseMenuMapper.queryAdminFunctions();
            //将集合中的字符串集去重以逗号分割拼接成字符串
            loginUserFunctions = String.join(",", adminFunction);
//            loginUserFunctions = CommonUtil.removeRepeatCode(adminFunction, "functionCode");
        }
        //去除重复字符串
        loginUserFunctions = CommonUtil.removeRepeatStr(loginUserFunctions);

        //当前登录账户拥有功能的完整树集合
        List<Map<String, Object>> ownFunctionList = baseMenuMapper.queryFunctionInfoByCodesPart(loginUserFunctions);
        //当前登录账户拥有功能的树结构
        List<Map<String, Object>> ownFunctionMapList = StringUtil.listToTree(ownFunctionList, "functionCode", "parentFunctionCode", "childrenList");

        //2.所选角色已分配菜单功能权限(非递归)
        String allotFunction = baseRoleFunctionsMapper.queryRoleFunctionByRoleCode(roleCode);
        //已分配功能树状结构集合
        List<Map<String, Object>> allotFunctionTreeList = baseMenuMapper.queryFunctionInfoByCodesPart(allotFunction);
        resultMap.put("ownFunction", ownFunctionMapList);
        resultMap.put("allotFunction", allotFunctionTreeList);
        return resultMap;

    }

    /**
     * Function Name               modifyRoleFunctionAllotAndRemove
     *
     * @param roleCode
     * @param functionCodes
     * @return
     * @description 角色功能分配与移除
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年6月7日 上午11:38:29          SharpClaw_x                     Initial
     * *********************************************************************
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void modifyRoleFunctionAllotAndRemove(String roleCode, String functionCodes) {

        //根据角色代码删除角色拥有的所有功能
        baseRoleFunctionsMapper.deleteAllRoleFunctionByRoleCode(roleCode);
        if (StringUtils.isEmpty(functionCodes)) {
            functionCodes = "";
        }

        //传入功能代码字符串为空,则表示移除所有已分配功能
        String[] functionCodeGroup = functionCodes.split(",");
        for (int i = 0; i < functionCodeGroup.length; i++) {
            TBaseRoleFunctions tBaseRoleFunctions = new TBaseRoleFunctions();
            tBaseRoleFunctions.setRoleFuncionId(UUID.randomUUID().toString());
            tBaseRoleFunctions.setFunctionCode(functionCodeGroup[i]);
            tBaseRoleFunctions.setRoleCode(roleCode);
            baseRoleFunctionsMapper.insert(tBaseRoleFunctions);
        }
    }


    /**
     * Function Name               loadDataByRoleCode
     *
     * @param loginUserCode
     * @param roleCode
     * @return
     * @description 根据角色代码查询已分配数据权限和未分配数据权限
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年6月7日 下午2:43:25          SharpClaw_x                     Initial
     * *********************************************************************
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    @Transactional
    public Map<String, Object> loadDataByRoleCode(String loginUserCode, String roleCode) {

        if (StringUtils.isEmpty(loginUserCode)) {
            loginUserCode = "";
        }
        if (StringUtils.isEmpty(roleCode)) {
            roleCode = "";
        }

        Map resultMap = new HashMap<>();

        int adminFlag = loginMapper.checkAdminByUserId(loginUserCode);
        String loginUserManagementScope = "";
        if (adminFlag == 0) {
            loginUserManagementScope = baseOrgMapper.loadDataScopeByUserCodeUnion(loginUserCode);
        } else {
            loginUserManagementScope = baseOrgMapper.queryAdminOrgCodes();
        }
        //当前登录用户拥有数据权限去重
        loginUserManagementScope = CommonUtil.removeRepeatStr(loginUserManagementScope);
        //当前登录用户拥有数据权限树集合
        List<Map<String, Object>> ownDataTreeList = baseRoleMapper.queryDataByCodesPart(loginUserManagementScope);
        //当前登录用户拥有数据权限树集合
        List<Map<String, Object>> ownDataMapList = StringUtil.listToTree(ownDataTreeList, "orgCode", "parentOrgCode", "childrenList");

        //查询选择角色已分配数据信息权限字符串-非递归
        String allotDataScope = baseRoleFunctionsMapper.loadDataScopeByRoleCode(roleCode);
        //去重
        allotDataScope = CommonUtil.removeRepeatStr(allotDataScope);
        //已分配数据权限树集合
        List<Map<String, Object>> allotDataTreeList = baseRoleMapper.queryDataByCodesPart(allotDataScope);

        resultMap.put("ownAllotData", ownDataMapList);
        resultMap.put("allotData", allotDataTreeList);

        return resultMap;

    }


    /**
     * Function Name               modifyRoleDataAllotAndRemove
     *
     * @param checkRoleCode
     * @param orgCodes
     * @return
     * @description 根据角色编号, 数据权限代码字符串 进行数据权限的分配与移除
     * Modify History:              Date             Programmer       Notes
     * ---------        ---------------  ---------
     * 2017年6月7日 下午4:57:37          SharpClaw_x                     Initial
     * *********************************************************************
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void modifyRoleDataAllotAndRemove(String checkRoleCode, String orgCodes) {

        if (StringUtils.isEmpty(orgCodes)) {
            orgCodes = "";
        }

        //根据数据权限范围更新数据权限
        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("roleCode", checkRoleCode);
        paramsMap.put("orgCodes", orgCodes);
        baseRoleMapper.modifyRoleDataScopeByRoleCode(paramsMap);
    }

}
